iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
自我挑戰組

30 天養大一個開源專案:baodao-skill 從零開始系列 第 22 篇

【Day 22】一個 JSON 裝 144 間博物館:「故宮」搜出兩個答案,64 間不用錢

  • 分享至 

  • xImage
  •  

先講結論:taiwan-museum 抓文化部文化地圖的博物館類開放資料(emap typeId=H),免金鑰免登入,單次回傳全量。2026-09-29 實測:HTTP 200、127,549 bytes、144 館,欄位含分類、地址、票價、電話、WGS84 經緯度、官網連結。查「週末去哪逛」這種問題,127KB 就夠了。

實測:故宮有兩個,免費的有 64 間

第一個小陷阱:用名字搜「故宮」會先撈到國立故宮博物院南部院區(嘉義太保,故宮大道 888 號),本館在臺北士林至善路二段 221 號。名錄裡同名系館不是異常,回報時要給全名加地址,不能只看名字命中就答。2026-09-29 實測分佈:

指標 實測值
總館數 144
歷史與人文 / 藝術與工藝 60 / 36
綜合與其他 / 自然與科學 24 / 24
臺北市館數(最多) 41
ticketPrice 含「免費」 64 間

順帶,縣市欄位寫「臺北市」是臺不是台——台臺之亂在這個資料集繼續適用,比對前兩邊都正規化。

票價是自由文字,別幫它四捨五入

ticketPrice 不是數字欄位,是全文:本館寫「普通參觀券 一般觀眾 350元 優惠參觀券 1.國人憑身分證件(團體亦同)2.持中華民國外僑永久居留證……」。SKILL 的規矩是逐字引用,不自行歸納成「350 元」——優惠條件被吃掉,答案就失真了。這跟停車場的 -9 是同一個哲學:欄位是什麼型態,就給什麼型態的答案。

查法(實測可跑)

import json
d = json.load(open('/tmp/museum.json'))
for m in d:
    if '故宮' in m['name']:                       # 注意:會命中本館與南部院區
        print(m['name'], m['address'], m.get('phone',''))

資料源:cloud.culture.tw/frontsite/trans/emapOpenDataAction.do?method=exportEmapJson&typeId=H,要帶瀏覽器 UA。經緯度是字串,算距離前轉 float;缺值就改用地址回答。

名錄不是即時,這句話要講在前面

名錄查不到休館日、特展、整修閉館——這些要引導到各館官網(website 欄位,但 144 館只有 102 館有值,2026-09-29 實測,部分條目連鍵都沒有,要用 .get() 取)。「故宮在士林至善路二段 221 號,普通票 350 元;這是文化部 2026-09 名錄資料」——附上名錄月份,使用者就知道資訊的邊界在哪。另外文化部的「博物館」類不含一般文創園區和藝廊,找那些要說明範圍不同。

錯誤處理(寫進 SKILL 的規矩)

  • curl 失敗先帶瀏覽器 UA 重試;持續失敗回報資料源異常,不編館名。
  • 票價自由文字逐字引用;空白欄位用 .get()。
  • 名錄非即時:開館狀態、特展引導官網;144 館不等於全台展場。
  • 經緯度字串轉 float,缺值用地址。

第 22 天。144 間博物館裝在一個 JSON 裡很省事,但「故宮」有兩個、票價是一段文章、官網欄位三分之一是空的——名錄類資料的誠實用法,是把邊界也一起回答。


上一篇
【Day 21】寫這篇的今天剛好放假:6,499 bytes 的人事總處日曆,和一年一變的編碼
下一篇
【Day 23】完全不連網的 skill:統編檢核的數學,和文件驗收案例被抓包的一天
系列文
30 天養大一個開源專案:baodao-skill 從零開始 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言